package cn.hnucm.searchesservice.dao.impl;

import cn.hnucm.searchesservice.dao.TbLogDao;
import cn.hnucm.searchesservice.entity.TbLog;
import cn.hnucm.searchesservice.utils.MyInterId;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @author: chenjintao
 * @Date: 2021/12/20 23:21
 */
@Controller
public class TbLogDaoImpl implements TbLogDao {

    @Autowired
    @Qualifier("getRestHighLevelClient")
    private RestHighLevelClient client;


    /**
     * 获取所有的日志
     *
     * @return
     */
    @Override
    public List<TbLog> getAllLog() {
        SearchRequest request = new SearchRequest("tb_log");
        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            ArrayList<TbLog> logs = new ArrayList<>();
            for (SearchHit hit : response.getHits()) {
                TbLog log = new TbLog();
                try {
                    log.setLogId(Integer.valueOf(hit.getId()));
                }catch (Exception e){
                    e.printStackTrace();
                }
                loadingLog(log, new JSONObject(hit.getSourceAsString()));
                logs.add(log);
            }
            return logs;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 增加一条日志
     *
     * @param tbLog
     * @return
     */
    @Override
    public Boolean addLog(TbLog tbLog) {
        if (tbLog.getLogId() == null) tbLog.setLogId(MyInterId.getIntegerId());
        IndexRequest request = new IndexRequest("tb_log","_doc",String.valueOf(tbLog.getLogId()));
        request.source(JSON.toJSONString(tbLog), XContentType.JSON);
        try {
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            //elasticsearch 插入成功返回发状态码为201
            return response.getResult().toString().equalsIgnoreCase("CREATED");
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 通过日志Id删除一条日志
     *
     * @param logId
     * @return
     */
    @Override
    public Boolean deleteLogById(Integer logId) {
        DeleteRequest request = new DeleteRequest("tb_log", String.valueOf(logId));
        try {
            DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
            return response.getResult().toString().equalsIgnoreCase("deleted");
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 通过日志Id查询一条日志
     *
     * @param logId
     * @return
     */
    @Override
    public TbLog selectLogById(Integer logId) {
        GetRequest request = new GetRequest("tb_log", String.valueOf(logId));
        try {
            GetResponse response = client.get(request, RequestOptions.DEFAULT);

            TbLog tbLog = new TbLog();
            try {
                tbLog.setLogId(Integer.valueOf(response.getId()));
            }catch (Exception e){
                e.printStackTrace();
            }
            loadingLog(tbLog, new JSONObject(response.getSourceAsString()));
            return tbLog;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 批量查询日志,根据多层因素
     *
     * @param userId
     * @param operation
     * @param method
     * @return
     */
    @Override
    public List<TbLog> selectLog(Integer userId, String operation, String method,
                                 Integer pageFrom, Integer pageSize) {
        SearchRequest request = new SearchRequest("tb_log");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (userId != null) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("userId", String.valueOf(userId)));
        }
        if (operation != null) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("operation", operation));
        }
        if (method != null) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("method", method));
        }
//        //升序  好像无法排序字符串
//        builder.sort("createTime",SortOrder.ASC);
        //分页设置
        builder.from(pageFrom);
        builder.size(pageSize);
        builder.query(boolQueryBuilder);
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            ArrayList<TbLog> logs = new ArrayList<>();
            for (SearchHit hit : response.getHits().getHits()) {
                TbLog log = new TbLog();
                try {
                    log.setLogId(Integer.valueOf(hit.getId()));
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println(hit.getSourceAsString());
                loadingLog(log, new JSONObject(hit.getSourceAsString()));
                logs.add(log);
            }
            return logs;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }


    }


    /**
     * 装填除logId以外的其他属性
     *
     * @param tbLog
     * @param jsonObject
     */
    private void loadingLog(TbLog tbLog, JSONObject jsonObject) {
        try {
            tbLog.setUserId(jsonObject.getInt("userId"));
            tbLog.setOperation(jsonObject.getString("operation"));
            tbLog.setMethod(jsonObject.getString("method"));
            tbLog.setParams(jsonObject.getString("params"));
            tbLog.setTime(jsonObject.getLong("time"));
            tbLog.setIp(jsonObject.getString("ip"));
            tbLog.setCreateTime(jsonObject.getString("createTime"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}
